<template>
  <BasicDrawer
    v-bind="$attrs"
    :closable="false"
    getContainer="body"
    width="100%"
    title="新增"
    @register="registerDrawer"
  >
    <div class="actions aciton-shadow absolute bottom-0 flex items-center justify-end h-64px px-6">
      <a-button type="default" @click="handleCancel">取消</a-button>
      <a-button type="primary" class="ml-4" @click="handleSumbit">保存</a-button>
    </div>

    <div :class="prefixCls" class="flex flex-col mt-3 aciton-shadow h-full overflow-y-auto">
      <Spin :spinning="loading">
        <div class="form-content flex-1 pb-12">
          <Collapse class="form-coll" v-model:activeKey="activeKey">
            <CollapsePanel key="1" header="基本信息">
              <div class="pl-10">
                <BasicForm @register="registerForm" />
              </div>
            </CollapsePanel>
            <CollapsePanel key="2" header="数据源定义">
              <div class="pl-10">
                <BasicForm @register="registerData" />
              </div>
            </CollapsePanel>
            <!-- 表头定义 -->
            <CollapsePanel key="3" :header="getFieldTitle">
              <MTable
                isCopy
                v-if="tableDesignInfo[getKeyField] && !loading"
                :columns="titleColumns(classify)"
                v-model:data="tableDesignInfo[getKeyField]"
                @add="handleAdd()"
                @copy="handleCopy"
                @edit="handleEdit"
                :showEvent="
                  (item) =>
                    classify === MODEL_TYPE.FORM && item.componentType !== ComponentTypeEnum.Hide
                "
              >
                <template #head>
                  <div class="ml-4">
                    <a-button @click="getDBFeilds">库表获取</a-button>
                    <a-button class="ml-2" @click="getDefineFeilds">定义表获取</a-button>
                    <template v-if="classify === MODEL_TYPE.FORM">
                      <a-button class="ml-2" @click="showFormAuth">流程表单权限 </a-button>
                      <!-- <a-button class="ml-2" @click="handleEvent(tableDesignInfo, true)">
                        事件定义
                      </a-button> -->
                    </template>
                  </div>
                </template>
              </MTable>
            </CollapsePanel>
            <CollapsePanel key="4" header="操作按钮">
              <MTable
                v-if="tableDesignInfo.tableButtons && !loading"
                v-model:data="tableDesignInfo.tableButtons"
                @add="handleAdd('tableButtons')"
                @edit="
                  (data) => {
                    handleEdit(data, 'tableButtons');
                  }
                "
              />
            </CollapsePanel>

            <CollapsePanel key="5" v-if="classify === MODEL_TYPE.LIST" header="缺省排序定义">
              <div class="my-4">
                <DefSortConfig
                  :data="tableDesignInfo.defSort"
                  @add="handleAddField()"
                  @del="handleDelField"
                  @del-mutil="handleDelMutilField"
                  :fields="tableDesignInfo.titles"
                />
              </div>
            </CollapsePanel>
          </Collapse>
        </div>
      </Spin>
    </div>
    <ButtonConfigModal :classify="classify" @register="registerModal" @success="handleSuccess" />
    <TableTitleConfigModal @register="registerTModal" @success="handleSuccess" />
    <FormFieldConfigModal @register="registerFModal" @success="handleSuccess" />
    <FormAuthModal @register="registerFormAuthModal" />
  </BasicDrawer>
</template>

<script lang="ts" setup name="ModelForm">
  import { ref, unref, computed } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { Collapse, Spin } from 'ant-design-vue';
  import MTable from './MTable.vue';
  import DefSortConfig from './DefSortConfig.vue';
  import ButtonConfigModal from './components/ButtonConfigModal.vue';
  import TableTitleConfigModal from './components/TableTitleConfigModal.vue';
  import FormFieldConfigModal from './components/FormFieldConfigModal.vue';
  import FormAuthModal from './components/form-auth/index.vue';

  import { useModal } from '/@/components/Modal';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useEchoTableConfig, useEchoFormConfig } from './hooks';
  // import { useRouter } from 'vue-router';
  import { basicSchemaFn, dataSchema, titleColumns } from './form.data';
  import { ModelListItem } from '/@/api/config-center/model';
  import { ComponentTypeEnum } from '/@/components/ModelTable/src/types';

  import {
    MODEL_TYPE,
    getModelInfoApi,
    saveModelApi,
    updateModelApi,
    getFieldsFromDbListApi,
    getFieldsFromTableDefineListApi,
  } from '/@/api/config-center/model-design';
  import { cloneDeep } from 'lodash-es';

  const CollapsePanel = Collapse.Panel;

  const props = withDefaults(
    defineProps<{
      classify: MODEL_TYPE;
    }>(),
    {
      classify: MODEL_TYPE.LIST,
    },
  );
  const emit = defineEmits<{
    (e: 'success'): void;
    (e: 'register', value: any): any;
  }>();

  const getFieldTitle = computed(() =>
    props.classify === MODEL_TYPE.FORM ? '字段定义' : '表头定义',
  );
  const getKeyField = computed(() => (props.classify === MODEL_TYPE.FORM ? 'schemas' : 'titles'));
  const { createMessage } = useMessage();

  let id = '';

  const { prefixCls } = useDesign('model-form');
  const loading = ref(false);
  // 模型基础配置
  const [
    registerForm,
    { validateFields: basicV, resetFields, setFieldsValue: basicSets, updateSchema: basicUpdate },
  ] = useForm({
    labelWidth: 110,
    colon: false,
    baseColProps: { lg: 11, md: 23 },
    schemas: basicSchemaFn(props.classify),
    showActionButtonGroup: false,
  });
  const [
    registerData,
    { validateFields: dataV, resetFields: dataReset, setFieldsValue: dataSets },
  ] = useForm({
    labelWidth: 110,
    colon: false,
    baseColProps: { lg: 11, md: 23 },
    schemas: dataSchema,
    showActionButtonGroup: false,
  });

  // 模型个性化配置
  const tableDesignInfo = ref<Indexable<any>>({
    pageSize: 10,
    defSort: [],
    event: {},
    titles: null,
    schemas: null,
    tableButtons: null,
  });
  const isUpdate = ref(false);

  // 初始化
  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    resetFields();
    dataReset();

    isUpdate.value = !!data?.isUpdate;
    id = data.record?.modelId;
    basicUpdate([
      {
        field: 'modelCode',
        ifShow: isUpdate.value,
      },
      {
        field: 'client',
        dynamicDisabled: isUpdate.value,
      },
    ]);
    setDrawerProps({ title: data.record ? '编辑' : '新增', destroyOnClose: !data?.isUpdate });
    if (data.record) {
      await init(id);
    } else {
      tableDesignInfo.value = {
        defSort: [],
        titles: [] as Indexable[],
        schemas: [],
        tableButtons: [] as Indexable[],
        event: {},
      };
    }
  });

  // 手风琴交互
  const activeKey = ref(['1', '2', '3', '4']);
  // 用于通用修改配置方法的key
  const modelKey = ref('tableButtons');
  const [registerModal, { openModal: tableButtonsModal }] = useModal();
  const [registerTModal, { openModal: titlesModal }] = useModal();
  const [registerFModal, { openModal: schemasModal }] = useModal();
  // const [registerEventModal, { openModal: eventModal }] = useModal();
  const [registerFormAuthModal, { openModal: formAuthModal }] = useModal();

  const openModal = {
    tableButtonsModal,
    titlesModal,
    schemasModal,
  };
  // 提交存储 后端给什么就提交什么
  let baseObj: ModelListItem | {} = {};

  async function init(modelId) {
    if (modelId) {
      try {
        loading.value = true;
        const data = await getModelInfoApi(modelId as string);

        if (data.modules) {
          data.modules = undefined;
        }

        basicSets(data);
        dataSets(data.dataInfo);
        // formDesignInfo
        if (props.classify === MODEL_TYPE.LIST) {
          if (data.tableDesignInfo) {
            tableDesignInfo.value = useEchoTableConfig(data.tableDesignInfo, basicSets);
          }
        } else {
          if (data.formDesignInfo) {
            tableDesignInfo.value = useEchoFormConfig(data.formDesignInfo, basicSets);
          }
        }

        baseObj = data;
      } catch (e: any) {
        createMessage.error(e.msg || JSON.stringify(e));
        throw e;
      } finally {
        loading.value = false;
      }
    }
  }

  const handleAdd = (key = unref(getKeyField)) => {
    modelKey.value = key;

    openModal[key + 'Modal'](true, {
      isUpdate: false,
    });
  };
  const handleEdit = (record, key = unref(getKeyField)) => {
    modelKey.value = key;

    openModal[key + 'Modal'](true, {
      record,
      isUpdate: true,
    });
  };
  const handleCopy = ({ record, index }) => {
    const item = cloneDeep(record);
    item.dataIndex = `copy_${record.dataIndex}`;
    item.title = `copy_${record.title}`;

    tableDesignInfo.value[unref(getKeyField)].splice(index + 1, 0, item);
  };

  // const handleEvent = (record, isForm = false) => {
  //   eventModal(true, {
  //     record,
  //     isForm,
  //   });
  // };
  const handleCancel = () => {
    closeDrawer();
  };

  const handleSuccess = ({ isUpdate, index, record }) => {
    if (isUpdate) {
      tableDesignInfo.value[modelKey.value].splice(index, 1, record);
      return;
    }
    tableDesignInfo.value[modelKey.value].push(record);
  };

  const handleSumbit = async () => {
    try {
      const params = await basicV();

      const dataInfo = await dataV();
      const tableInfo = unref(tableDesignInfo);

      if (!tableInfo[unref(getKeyField)].length) {
        createMessage.warn(`请添加${unref(getFieldTitle)}定义`);
        return;
      }

      params.modelId = id;
      params.dataInfo = dataInfo;
      if (props.classify === MODEL_TYPE.LIST) {
        if (!tableInfo.defSort.length) {
          createMessage.warn(`请添加缺省排序定义`);
          return;
        }
        const {
          apiCode,
          title,
          tableType,
          parentIdField,
          childrenIdField,
          pageSize,
          redo,
          setting,
          checkbox,
          meta,
          listTemplateType,
          appCenterRow,
        } = params;
        const tableSetting = {
          redo,
          setting,
          fullScreen: false,
        };
        Object.assign(tableInfo, {
          pageSize,
          tableSetting,
          checkbox,
          tableType,
          parentIdField,
          childrenIdField,
          title,
          apiCode,
          meta,
          listTemplateType,
          appCenterRow,
        });

        params.tableDesignInfo = tableInfo;
      } else {
        tableInfo.btns = tableInfo.tableButtons;
        const { tableButtons, schemas, event } = tableInfo;

        const { layout, colSpan, title, labelWidth, labelSpan, labelAlign, isReadonly } = params;
        params.formDesignInfo = {
          schemas,
          btns: tableButtons,
          layout,
          colSpan,
          labelSpan,
          labelWidth,
          labelAlign,
          event,
          isReadonly,
          title,
        };
      }
      delete params.meta;
      delete params.listTemplateType;
      delete params.appCenterRow;
      baseObj = {
        ...baseObj,
        ...params,
        classify: props.classify,
      };
      loading.value = true;
      setDrawerProps({ confirmLoading: true });

      const ajaxFn = id ? updateModelApi : saveModelApi;
      await ajaxFn(baseObj as ModelListItem);
      createMessage.success('操作成功');
      emit('success');
      handleCancel();
    } catch (e: any) {
      e.errorFields && createMessage.error(e.errorFields[0].errors);
      throw e;
    } finally {
      loading.value = false;
      setDrawerProps({ confirmLoading: false });
    }
  };

  // === 字段获取 start ===
  const getDBFeilds = async () => {
    const ret = await getDBTableParams();

    if (!ret) return;

    const data = await getFieldsFromDbListApi(ret);

    setTitles(data);
  };

  const getDefineFeilds = async () => {
    const ret = await getDBTableParams();
    if (!ret) return;
    const data = await getFieldsFromTableDefineListApi(ret);

    setTitles(data);
  };

  async function setTitles(data: any[]) {
    const key = unref(getKeyField);
    const titles = tableDesignInfo.value[key];

    let name = 'title';
    let code = 'dataIndex';

    if (props.classify === MODEL_TYPE.FORM) {
      code = 'field';
      name = 'label';
    }
    const dataIndexs = titles.map((el) => el[code]);

    const newDataInexs = data
      .filter((el) => !dataIndexs.includes(el.name))
      .map((el) => ({ [name]: el.title || el.name, [code]: el.name }));

    if (newDataInexs.length) {
      tableDesignInfo.value[key] = titles.concat(newDataInexs);
    }
  }

  async function getDBTableParams() {
    try {
      return await dataV(['dataSource', 'tableCode']);
    } catch (e: any) {
      if (e.errorFields) {
        const res = e.errorFields[0].errors;
        createMessage.warn(res);
      }
    }
  }

  // === 字段获取end ===

  // 默认排序
  const handleAddField = () => {
    tableDesignInfo.value.defSort.push({ asc: 1 });
  };
  const handleDelField = (idx) => {
    tableDesignInfo.value.defSort.splice(idx, 1);
  };
  const handleDelMutilField = (arr) => {
    tableDesignInfo.value.defSort = arr || [];
  };

  function showFormAuth() {
    const schemas = tableDesignInfo.value.schemas;

    if (!schemas.length) return createMessage.warning('请添加字段');
    formAuthModal(true, {
      schemas,
      modelId: id,
    });
  }
</script>

<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-model-form';

  .actions {
    z-index: 2;
    width: 100%;
    background-color: @component-background;
  }

  .@{prefix-cls} {
    ::v-deep(.ant-collapse) {
      background: #fcfdff !important;
      border: none !important;
      box-shadow: -4px 0 16px 0 rgba(143, 161, 185, 0.16);

      .ant-collapse-header {
        background-color: #f7faff !important;
        padding: 17px 16px !important;
        font-weight: 700;
      }

      > .ant-collapse-item {
        border-bottom: 1px solid #e1eaf4 !important;
      }

      .ant-collapse-content {
        border-top: 1px solid #e1eaf4 !important;
      }
    }

    .form-content {
      background: rgba(9, 120, 255, 0.02);
    }
  }
</style>
